home *** CD-ROM | disk | FTP | other *** search
- /*
- * objects.c
- *
- * This file is part of the basis of the Forms Library
- *
- * It contains all basic routines that deal with objects, like making
- * them, changing them, drawing them, and sending events to them.
- *
- * Written by Mark Overmars
- *
- * Version 2.2 b
- * Date: Jun 18, 1993
- */
-
- #include <stdio.h>
- #include <sys/types.h>
- #include <string.h>
- #include "gl/gl.h"
- #include "gl/device.h"
- #include <malloc.h>
- #include "forms.h"
-
- /*-----------------------------------------------------------------------
- Creation routines
- -----------------------------------------------------------------------*/
-
- FL_FORM *fl_make_form(float w,float h)
- /* Creates an empty form. NOT FOR USER. */
- {
- FL_FORM *form;
- form = (FL_FORM *) fl_malloc(sizeof(FL_FORM));
- form->w = w; form->h = h;
- form->window = -1;
- form->deactivated = 1;
- form->visible = 0;
- form->frozen = 0;
- form->form_call_back = NULL;
- form->focusobj = NULL;
- form->first = NULL;
- form->last = NULL;
- form->doublebuf = fl_doublebuf;
- form->hotx = form->hoty = -1;
- return form;
- }
-
- FL_OBJECT *fl_make_object(int objclass,int type,float x,float y,
- float w,float h, const char *label,FL_HANDLEPTR handle)
- /* Creates an object, NOT FOR USER. */
- {
- FL_OBJECT *ob;
- ob = (FL_OBJECT *) fl_malloc(sizeof(FL_OBJECT));
- ob->objclass = objclass;
- ob->type = type;
- ob->boxtype = FL_NO_BOX;
- ob->x = x; ob->y = y; ob->w = w; ob->h = h;
- ob->label = (char *) fl_malloc(strlen(label)+1);
- strcpy(ob->label,label);
- ob->handle = handle;
- ob->align = FL_ALIGN_CENTER;
- ob->lcol = 0;
- ob->lsize = FL_NORMAL_FONT;
- ob->lstyle = FL_NORMAL_STYLE;
- ob->shortcut = (char *) fl_malloc(1);
- ob->shortcut[0] = '\0';
- ob->pushed = 0;
- ob->focus = 0;
- ob->belowmouse = 0;
- ob->input = 0;
- ob->wantall = 0;
- ob->active = 1;
- ob->visible = 1;
- ob->radio = 0;
- ob->automatic = 0;
- ob->object_call_back = NULL;
- ob->spec = NULL;
- ob->next = NULL;
- ob->prev = NULL;
- ob->form = NULL;
- return ob;
- }
-
- void fl_free_object(FL_OBJECT *obj)
- /* Frees the memory used by an object. */
- {
- /* check whether ok to free it */
- if (obj == NULL)
- { fl_error("fl_free_object","Trying to free NULL object."); return;}
- if (obj->form != NULL)
- { fl_error("fl_free_object","Freeing non-deleted object."); fl_delete_object(obj);}
- /* free object */
- if (obj->label != NULL) free(obj->label);
- if (obj->shortcut != NULL) free(obj->shortcut);
- fl_handle_object(obj, FL_FREEMEM, 0.0, 0.0, 0);
- free(obj);
- }
-
- void fl_free_form(FL_FORM *form)
- /* Frees the memory used by an form, together with all its objects. */
- {
- FL_OBJECT *current, *next;
- /* check whether ok to free */
- if (form == NULL)
- { fl_error("fl_free_form","Trying to free NULL form."); return;}
- if (form->visible)
- { fl_error("fl_free_form","Freeing visible form."); fl_hide_form(form);}
- /* free the objects */
- for(next = form->first; next != NULL; )
- {
- current = next;
- next = current->next;
- if (current->label != NULL) free(current->label);
- if (current->shortcut != NULL) free(current->shortcut);
- fl_handle_object(current, FL_FREEMEM, 0.0, 0.0, 0);
- free(current);
- }
- /* free the form structure */
- free(form);
- }
-
- void fl_add_object(FL_FORM *form, FL_OBJECT *obj)
- /* Adds an object to the form. */
- {
- /* Checking for correct behaviour. */
- if (obj == NULL)
- { fl_error("fl_add_object","Trying to add NULL object."); return;}
- if (form == NULL)
- { fl_error("fl_add_object","Trying to add object to NULL form."); return;}
- obj->prev = obj->next = NULL;
- if (form->first == NULL)
- form->first = form->last = obj;
- else
- {
- obj->prev = form->last;
- form->last->next = obj;
- form->last = obj;
- }
- obj->form = form;
- if (obj->input && form->focusobj == NULL) fl_set_object_focus(form,obj);
- fl_redraw_object(obj);
- }
-
- void fl_insert_object(FL_OBJECT *obj, FL_OBJECT *before)
- /* Insert object obj before object before. */
- {
- FL_FORM *form;
- /* Checking for correct behaviour. */
- if (obj == NULL)
- { fl_error("fl_insert_object","Trying to insert NULL object."); return;}
- if (before == NULL)
- { fl_error("fl_insert_object","Trying to insert before NULL object."); return;}
- if (before->form == NULL)
- { fl_error("fl_insert_object","Trying to insert object to NULL form."); return;}
- form = before->form;
- obj->next = before;
- if (before == form->first)
- { form->first = obj; obj->prev = NULL; }
- else
- { obj->prev = before->prev; obj->prev->next = obj;}
- before->prev = obj;
- obj->form = form;
- if (obj->input && form->focusobj == NULL) fl_set_object_focus(form,obj);
- fl_redraw_form(form);
- }
-
- void fl_delete_object(FL_OBJECT *obj)
- /* Deletes an object from its form. */
- {
- FL_FORM *form;
- if (obj == NULL)
- { fl_error("fl_delete_object","Trying to delete NULL object."); return;}
- if (obj->form == NULL)
- { fl_error("fl_delete_object","Trying to delete from NULL form."); return;}
- form = obj->form;
- if (obj->focus) fl_set_object_focus(form,NULL);
- obj->form = NULL;
- if (obj->prev != NULL)
- obj->prev->next = obj->next;
- else
- form->first = obj->next;
- if (obj->next != NULL)
- obj->next->prev = obj->prev;
- else
- form->last = obj->prev;
- if (form->focusobj == NULL)
- fl_set_object_focus(form,fl_find_first(form,FL_FIND_INPUT,0.,0.));
- fl_redraw_form(form);
- }
-
- /*-----------------------------------------------------------------------
- Setting Attributes.
- -----------------------------------------------------------------------*/
-
- void fl_set_object_boxtype(FL_OBJECT *ob,int boxtype)
- /* Sets the boxtype of the object */
- {
- if (ob == NULL)
- { fl_error("fl_set_object_boxtype","Setting boxtype of NULL object."); return;}
- ob->boxtype = boxtype;
- fl_redraw_object(ob);
- }
-
- void fl_set_object_color(FL_OBJECT *ob,int col1,int col2)
- /* Sets the color of the object */
- {
- if (ob == NULL)
- { fl_error("fl_set_object_color","Setting color of NULL object."); return;}
- ob->col1 = col1;
- ob->col2 = col2;
- fl_redraw_object(ob);
- }
-
- void fl_set_object_label(FL_OBJECT *ob, const char *label)
- /* sets the label of an object */
- {
- if (ob == NULL)
- { fl_error("fl_set_object_label","Setting label of NULL object."); return;}
- if(label) /*TC */
- ob->label = (char *) realloc(ob->label,strlen(label)+1);
- strcpy(ob->label,label ? label:""); /*TC */
- fl_redraw_object(ob);
- }
-
- void fl_set_object_lcol(FL_OBJECT *ob,int lcol)
- /* sets the label color of an object */
- {
- if (ob == NULL)
- { fl_error("fl_set_object_lcol","Setting label color of NULL object."); return;}
- ob->lcol = lcol;
- fl_redraw_object(ob);
- }
-
- void fl_set_object_lsize(FL_OBJECT *ob,float lsize)
- /* sets the label size of an object */
- {
- if (ob == NULL)
- { fl_error("fl_set_object_lsize","Setting label size of NULL object."); return;}
- ob->lsize = lsize;
- fl_redraw_object(ob);
- }
-
- void fl_set_object_lstyle(FL_OBJECT *ob,int lstyle)
- /* sets the label style of an object */
- {
- if (ob == NULL)
- { fl_error("fl_set_object_lstyle","Setting label style of NULL object."); return;}
- ob->lstyle = lstyle;
- fl_redraw_object(ob);
- }
-
- void fl_set_object_align(FL_OBJECT *ob,int align)
- /* sets the label alignment of an object */
- {
- if (ob == NULL)
- { fl_error("fl_set_object_align","Setting label alignment of NULL object."); return;}
- ob->align = align;
- fl_redraw_object(ob);
- }
-
- void fl_activate_object(FL_OBJECT *ob)
- /* makes an object active if it was deactivated by fl_deactivate_object */
- {
- FL_OBJECT *obj = ob;
- if (ob == NULL)
- { fl_error("fl_activate_object","Trying to activate NULL object."); return;}
- if (ob->objclass == FL_BEGIN_GROUP)
- while ( ob != NULL && ob->objclass != FL_END_GROUP)
- {
- if (ob->active < 0 ) ob->active = 1;
- if (ob->input && ob->form->focusobj == NULL)
- fl_set_object_focus(ob->form,ob);
- ob = ob->next;
- }
- else
- {
- if (ob->active < 0 ) ob->active = 1;
- if (ob->input && ob->form->focusobj == NULL)
- fl_set_object_focus(ob->form,ob);
- }
- }
-
- void fl_deactivate_object(FL_OBJECT *ob)
- /* Deactivates an object */
- {
- FL_OBJECT *obj = ob;
- if (ob == NULL)
- { fl_error("fl_deactive_object","Trying to deactive NULL object."); return;}
- if (ob->objclass == FL_BEGIN_GROUP)
- while ( ob != NULL && ob->objclass != FL_END_GROUP)
- {
- if (ob->active > 0 ) ob->active = -1;
- if (ob == ob->form->focusobj )
- fl_set_object_focus(ob->form,
- fl_find_first(ob->form,FL_FIND_INPUT,0.0,0.0));
- ob = ob->next;
- }
- else
- {
- if (ob->active > 0 ) ob->active = -1;
- if (ob == ob->form->focusobj )
- fl_set_object_focus(ob->form,
- fl_find_first(ob->form,FL_FIND_INPUT,0.0,0.0));
- }
- }
-
- void fl_show_object(FL_OBJECT *ob)
- /* makes an object visible */
- {
- FL_OBJECT *obj = ob;
- if (ob == NULL)
- { fl_error("fl_show_object","Trying to show NULL object."); return;}
- if (ob->objclass == FL_BEGIN_GROUP)
- while ( ob != NULL && ob->objclass != FL_END_GROUP)
- {
- ob->visible = 1;
- if (ob->input && ob->form->focusobj == NULL)
- fl_set_object_focus(ob->form,ob);
- ob = ob->next;
- }
- else
- {
- ob->visible = 1;
- if (ob->input && ob->form->focusobj == NULL)
- fl_set_object_focus(ob->form,ob);
- }
- fl_redraw_object(obj);
- }
-
- void fl_hide_object(FL_OBJECT *ob)
- /* makes an object invisible */
- {
- FL_OBJECT *obj = ob;
- if (ob == NULL)
- { fl_error("fl_hide_object","Trying to hide NULL object."); return;}
- if (ob->objclass == FL_BEGIN_GROUP)
- while ( ob != NULL && ob->objclass != FL_END_GROUP)
- {
- ob->visible = 0;
- if (ob == ob->form->focusobj )
- fl_set_object_focus(ob->form,
- fl_find_first(ob->form,FL_FIND_INPUT,0.0,0.0));
- ob = ob->next;
- }
- else
- {
- ob->visible = 0;
- if (ob == ob->form->focusobj )
- fl_set_object_focus(ob->form,
- fl_find_first(ob->form,FL_FIND_INPUT,0.0,0.0));
- }
- fl_redraw_form(obj->form);
- }
-
- void fl_set_object_shortcut(FL_OBJECT *obj, const char *str)
- /* Sets the list of shortcuts for the object */
- {
- char sc[512];
- int i=0, j=0, offset=0;
- if (obj == NULL)
- { fl_error("fl_set_object_shortcut","Object is NULL."); return;}
- while (str[i] != '\0')
- {
- if (str[i] == '#')
- {
- offset = 128;
- }
- else if (str[i] == '^')
- {
- i++;
- if (str[i] >= 'A' && str[i] <= 'Z') sc[j++] = str[i]-'A'+1 + offset;
- else if (str[i] >= 'a' && str[i] <= 'z') sc[j++] = str[i]-'a'+1 + offset;
- else sc[j++] = str[i] + offset;
- offset = 0;
- }
- else
- {
- sc[j++] = str[i] + offset;
- offset = 0;
- }
- i++;
- }
- sc[j] = '\0';
- obj->shortcut = (char *) realloc(obj->shortcut,strlen(sc)+1);
- strcpy(obj->shortcut,sc);
-
- }
-
- void fl_set_object_focus(FL_FORM *form, FL_OBJECT *obj)
- /* Sets the object in the form on which the input is focussed. */
- {
- if (form == NULL)
- { fl_error("fl_set_object_focus","Setting focus in NULL form."); return;}
- if (obj == form->focusobj) return;
- fl_handle_object_direct(form->focusobj,FL_UNFOCUS,0.0,0.0,0);
- fl_handle_object_direct(obj,FL_FOCUS,0.0,0.0,0);
- }
-
- /*-----------------------------------------------------------------------
- Searching in forms
- -----------------------------------------------------------------------*/
-
- FL_OBJECT *fl_find_object(FL_OBJECT *obj,int find,float mx,float my)
- /* returns object in form starting at obj of type find */
- {
- while (obj != NULL)
- {
- if (obj->objclass != FL_BEGIN_GROUP && obj->objclass != FL_END_GROUP &&
- obj->visible && obj->active > 0)
- {
- if (find == FL_FIND_INPUT && obj->input) return obj;
- if (find == FL_FIND_AUTOMATIC && obj->automatic) return obj;
- if (find == FL_FIND_MOUSE && mx >= obj->x && mx <= obj->x+obj->w &&
- my >= obj->y && my <= obj->y + obj->h) return obj;
- }
- obj = obj->next;
- }
- return NULL;
- }
-
- FL_OBJECT *fl_find_first(FL_FORM *form,int find,float mx,float my)
- /* returns the first object of type find */
- {
- return ( fl_find_object(form->first,find,mx,my) );
- }
-
- FL_OBJECT *fl_find_last(FL_FORM *form,int find,float mx,float my)
- /* returns the last object of the type find */
- {
- FL_OBJECT *last, *obj;
- last = obj = fl_find_first(form,find,mx,my);
- while (obj != NULL)
- { last = obj; obj = fl_find_object(obj->next,find,mx,my); }
- return last;
- }
-
- /*-----------------------------------------------------------------------
- Drawing Routines.
- -----------------------------------------------------------------------*/
-
- static void redraw_marked(FL_FORM *form)
- /* Redraws all marked objects and reduces the mark */
- {
- FL_OBJECT *ob;
- if (!form->visible || form->frozen > 0) return;
- fl_save_user_window();
- fl_set_forms_window(form);
- ob = form->first;
- while (ob != NULL)
- {
- if (ob->visible && ob->redraw-- > 0) fl_handle_object(ob,FL_DRAW,0.,0.,0);
- ob = ob->next;
- }
- if (form->doublebuf) swapbuffers();
- fl_restore_user_window();
- }
-
- void fl_redraw_object(FL_OBJECT *obj)
- /* The actual drawing routine seen by the user */
- {
- FL_OBJECT *ob;
- int drawnumb;
- if (obj == NULL)
- { fl_error("fl_redraw_object","Trying to draw NULL object."); return;}
- if (obj->form == NULL) return;
- if (obj->form->doublebuf) drawnumb = 2; else drawnumb = 1;
- if (obj->objclass == FL_BEGIN_GROUP)
- {
- ob = obj;
- while ( (ob = ob->next) != NULL && ob->objclass != FL_END_GROUP )
- ob->redraw = drawnumb;
- }
- else
- obj->redraw = drawnumb;
- redraw_marked(obj->form);
- }
-
- void fl_redraw_form(FL_FORM *form)
- /* Draws a form */
- {
- FL_OBJECT *ob;
- int drawnumb;
- if (form == NULL)
- { fl_error("fl_redraw_form","Drawing NULL form."); return;}
- if (form->doublebuf) drawnumb = 2; else drawnumb = 1;
- ob = form->first;
- while ( ob != NULL )
- { ob->redraw = drawnumb; ob = ob->next; }
- redraw_marked(form);
- }
-
- void fl_freeze_object(FL_OBJECT *obj)
- /* Disables drawing of object */
- /* TO BE REMOVED */
- {
- fprintf(stderr, "fl_freeze_object() is obsolete. Use fl_freeze_form() instead\n");
- if (obj == NULL)
- { fl_error("fl_freeze_object","Freezing NULL object."); return;}
- fl_freeze_form(obj->form);
- }
-
- void fl_unfreeze_object(FL_OBJECT *obj)
- /* Enable drawing of object */
- /* TO BE REMOVED */
- {
- fprintf(stderr, "fl_unfreeze_object() is obsolete. Use fl_unfreeze_form() instead\n");
- if (obj == NULL)
- { fl_error("fl_freeze_object","Unfreezing NULL object."); return;}
- fl_unfreeze_form(obj->form);
- }
-
- void fl_freeze_form(FL_FORM *form)
- /* Disables drawing of form */
- {
- if (form == NULL)
- { fl_error("fl_freeze_form","Freezing NULL form."); return;}
- form->frozen++;
- }
-
- void fl_unfreeze_form(FL_FORM *form)
- /* Enable drawing of form */
- {
- if (form == NULL)
- { fl_error("fl_unfreeze_form","Unfreezing NULL form."); return;}
- if (form->frozen == 0)
- { fl_error("fl_unfreeze_form","Unfreezing non-frozen form."); return;}
- form->frozen--;
- if (form->frozen == 0) redraw_marked(form);
- }
-
- /*-----------------------------------------------------------------------
- Handling Routines.
- -----------------------------------------------------------------------*/
-
- static int fl_handle_it(FL_OBJECT *obj,int event,float mx,float my,char key)
- /* handles an event for an object */
- {
- if (obj == NULL) return 0;
- if (obj->objclass == FL_BEGIN_GROUP || obj->objclass ==FL_END_GROUP) return 0;
- if (obj->handle == NULL) return 0;
- switch (event)
- {
- case FL_ENTER: obj->belowmouse = 1; break;
- case FL_LEAVE: obj->belowmouse = 0; break;
- case FL_PUSH: obj->pushed = 1; break;
- case FL_RELEASE: if (! obj->radio) obj->pushed = 0; break;
- case FL_FOCUS: obj->form->focusobj = obj; obj->focus = 1; break;
- case FL_UNFOCUS: obj->form->focusobj = NULL; obj->focus = 0; break;
- }
- return (*(obj->handle))(obj,event,mx,my,key);
- }
-
- void fl_handle_object(FL_OBJECT *obj,int event,float mx,float my,char key)
- /* handle and store if successfull */
- { if (fl_handle_it(obj,event,mx,my,key)) fl_object_qenter(obj); }
-
- int fl_handle_object_direct(FL_OBJECT *obj,int event,float mx,float my,char key)
- /* handle but returns whether successfull */
- { return fl_handle_it(obj,event,mx,my,key); }
-
- /* TC: added to minimize redraw of forms in single buffer mode*/
- void fl_hide_object_only(FL_OBJECT *ob)
- {
- long owin = winget();
- int cols;
-
- if(fl_doublebuf) {fl_hide_object(ob); return; }
- if (ob == NULL)
- { fl_error("fl_hide_object_only","Trying to hide NULL object.");
- return;}
- if(!ob->visible || !ob->form->visible) {
- fl_hide_object(ob);
- return ;
- }
- /* here, difficult to guess what the form bk color is */
- if(ob->form->first->next->objclass == FL_BOX &&
- ob->form->first->next->type != FL_NO_BOX )
- cols = ob->form->first->next->col1;
- else
- cols = ob->form->first->col1;
- winset(ob->form->window);
- fl_color(cols);
- rectf(ob->x-0.2, ob->y-0.2, ob->x+ob->w-0.8,ob->y+ob->h-0.8);
- fl_drw_text_beside(ob->align, ob->x, ob->y, ob->w, ob->h,
- cols, ob->lsize, ob->lstyle, ob->label);
- ob->visible = 0;
- if(owin > 0) winset(owin);
- }
-